package dao

import (
	"gorm.io/gorm"
	"xlq-demo/app/model"
	"xlq-demo/library/db"
)

type CarDao struct{}

func NewCarDao() *CarDao {
	return new(CarDao)
}

func (carDao *CarDao) Create(car *model.Car) error {
	return db.GetMaster().Create(car).Error
}

func (carDao *CarDao) Delete(id interface{}) error {
	return db.GetMaster().Where("id=?", id).Delete(new(model.Car)).Error
}

func (carDao *CarDao) Update(id string, dataMap map[string]interface{}) error {
	return db.GetMaster().Model(new(model.Car)).Where("id=?", id).Updates(dataMap).Error
}

func (carDao *CarDao) Find(id interface{}) (*model.Car, error) {
	car := new(model.Car)
	err := db.GetSlave().Where("id=?", id).Take(car).Error
	if err == gorm.ErrRecordNotFound {
		err = nil
	}
	return car, err
}

func (carDao *CarDao) Get(ids []interface{}) ([]model.Car, error) {
	var cars []model.Car
	err := db.GetSlave().Find(&cars, ids).Error
	if err == gorm.ErrRecordNotFound {
		err = nil
	}
	return cars, err
}

func (carDao *CarDao) All() ([]model.Car, error) {
	var cars []model.Car
	err := db.GetSlave().Find(&cars).Error
	if err == gorm.ErrRecordNotFound {
		err = nil
	}
	return cars, err
}

func (carDao *CarDao) FindByWhere(wheres []string, params []interface{}, orders string) (*model.Car, error) {
	whereLen := len(wheres)
	car := new(model.Car)
	db := db.GetSlave()
	for i := 0; i < whereLen; i++ {
		db = db.Where(wheres[i], params[i])
	}
	if orders != "" {
		db = db.Order(orders)
	}
	err := db.Take(&car).Error
	if err == gorm.ErrRecordNotFound {
		err = nil
	}
	return car, err
}

func (carDao *CarDao) GetByWhere(wheres []string, params []interface{}, orders string) ([]model.Car, error) {
	whereLen := len(wheres)
	var cars []model.Car
	db := db.GetSlave()
	for i := 0; i < whereLen; i++ {
		db = db.Where(wheres[i], params[i])
	}
	if orders != "" {
		db = db.Order(orders)
	}
	err := db.Find(&cars).Error
	if err == gorm.ErrRecordNotFound {
		err = nil
	}
	return cars, err
}

func (carDao *CarDao) CountByWhere(wheres []string, params []interface{}) (int64, error) {
	whereLen := len(wheres)
	car := new(model.Car)
	db := db.GetSlave().Model(car)
	for i := 0; i < whereLen; i++ {
		db = db.Where(wheres[i], params[i])
	}
	var total int64
	err := db.Count(&total).Error
	return total, err
}

func (carDao *CarDao) ListByWhere(wheres []string, params []interface{}, orders string, offset, limit int) ([]model.Car, error) {
	var cars []model.Car
	db := db.GetSlave()
	for i := 0; i < len(wheres); i++ {
		db = db.Where(wheres[i], params[i])
	}
	if orders != "" {
		db = db.Order(orders)
	}
	err := db.Offset(offset).Limit(limit).Find(&cars).Error
	if err == gorm.ErrRecordNotFound {
		err = nil
	}
	return cars, err
}

func (carDao *CarDao) Raw(sql string, params []interface{}, out interface{}) error {
	err := db.GetSlave().Raw(sql, params...).Scan(out).Error
	if err == gorm.ErrRecordNotFound {
		err = nil
	}
	return err
}

func (carDao *CarDao) Exec(sql string, params []interface{}) error {
	return db.GetSlave().Exec(sql, params).Error
}
